package jdos.ints;

import jdos.Dosbox;
import jdos.hardware.IoHandler;
import jdos.hardware.Memory;
import jdos.hardware.VGA;
import jdos.misc.Log;
import jdos.types.LogSeverities;
import jdos.types.LogTypes;

public class Int10_put_pixel {

    static private boolean putpixelwarned = false;
    public static void INT10_PutPixel(/*Bit16u*/int x,/*Bit16u*/int y,/*Bit8u*/short page,/*Bit8u*/short color) {

        switch (Int10_modes.CurMode.type) {
        case VGA.M_EGA:
            {
                /* Set the correct bitmask for the pixel position */
                IoHandler.IO_Write(0x3ce,0x8);/*Bit8u*/short mask=(short)(128>>(x&7));IoHandler.IO_Write(0x3cf,mask);
                /* Set the color to set/reset register */
                IoHandler.IO_Write(0x3ce,0x0);IoHandler.IO_Write(0x3cf,color);
                /* Enable all the set/resets */
                IoHandler.IO_Write(0x3ce,0x1);IoHandler.IO_Write(0x3cf,0xf);
                /* test for xorring */
                if ((color & 0x80)!=0) { IoHandler.IO_Write(0x3ce,0x3);IoHandler.IO_Write(0x3cf,0x18); }
                //Perhaps also set mode 1
                /* Calculate where the pixel is in video memory */
                if (Int10_modes.CurMode.plength!=Memory.real_readw(Int10.BIOSMEM_SEG,Int10.BIOSMEM_PAGE_SIZE))
                    if (Log.level<=LogSeverities.LOG_ERROR) Log.log(LogTypes.LOG_INT10, LogSeverities.LOG_ERROR,"PutPixel_EGA_p: "+Integer.toString(Int10_modes.CurMode.plength, 16)+"!="+Integer.toString(Memory.real_readw(Int10.BIOSMEM_SEG,Int10.BIOSMEM_PAGE_SIZE),16));
                /*PhysPt*/int off=0xa0000+Memory.real_readw(Int10.BIOSMEM_SEG,Int10.BIOSMEM_PAGE_SIZE)*page+
                    ((y*Memory.real_readw(Int10.BIOSMEM_SEG,Int10.BIOSMEM_NB_COLS)*8+x)>>3);
                /* Bitmask and set/reset should do the rest */
                Memory.mem_readb(off);
                Memory.mem_writeb(off,0xff);
                /* Restore bitmask */
                IoHandler.IO_Write(0x3ce,0x8);IoHandler.IO_Write(0x3cf,0xff);
                IoHandler.IO_Write(0x3ce,0x1);IoHandler.IO_Write(0x3cf,0);
                /* Restore write operating if changed */
                if ((color & 0x80)!=0) { IoHandler.IO_Write(0x3ce,0x3);IoHandler.IO_Write(0x3cf,0x0); }
                break;
            }

        default:
            if(!putpixelwarned) {
                putpixelwarned = true;
                if (Log.level<=LogSeverities.LOG_ERROR) Log.log(LogTypes.LOG_INT10,LogSeverities.LOG_ERROR,"PutPixel unhandled mode type "+Int10_modes.CurMode.type);
            }
            break;
        }
    }

    public static short INT10_GetPixel(/*Bit16u*/int x,/*Bit16u*/int y,/*Bit8u*/short page) {
        int color = 0;
        switch (Int10_modes.CurMode.type) {
        case VGA.M_EGA:
            {
                /* Calculate where the pixel is in video memory */
                if (Int10_modes.CurMode.plength!=Memory.real_readw(Int10.BIOSMEM_SEG,Int10.BIOSMEM_PAGE_SIZE))
                    if (Log.level<=LogSeverities.LOG_ERROR) Log.log(LogTypes.LOG_INT10,LogSeverities.LOG_ERROR,"GetPixel_EGA_p: "+Integer.toString(Int10_modes.CurMode.plength, 16)+"!="+Integer.toString(Memory.real_readw(Int10.BIOSMEM_SEG,Int10.BIOSMEM_PAGE_SIZE),16));
                /*PhysPt*/int off=0xa0000+Memory.real_readw(Int10.BIOSMEM_SEG,Int10.BIOSMEM_PAGE_SIZE)*page+
                    ((y*Memory.real_readw(Int10.BIOSMEM_SEG,Int10.BIOSMEM_NB_COLS)*8+x)>>3);
                /*Bitu*/int shift=7-(x & 7);
                /* Set the read map */
                color=0;
                IoHandler.IO_Write(0x3ce,0x4);IoHandler.IO_Write(0x3cf,0);
                color|=((Memory.mem_readb(off)>>shift) & 1) << 0;
                IoHandler.IO_Write(0x3ce,0x4);IoHandler.IO_Write(0x3cf,1);
                color|=((Memory.mem_readb(off)>>shift) & 1) << 1;
                IoHandler.IO_Write(0x3ce,0x4);IoHandler.IO_Write(0x3cf,2);
                color|=((Memory.mem_readb(off)>>shift) & 1) << 2;
                IoHandler.IO_Write(0x3ce,0x4);IoHandler.IO_Write(0x3cf,3);
                color|=((Memory.mem_readb(off)>>shift) & 1) << 3;
                break;
            }

        default:
            if (Log.level<=LogSeverities.LOG_ERROR) Log.log(LogTypes.LOG_INT10,LogSeverities.LOG_ERROR,"GetPixel unhandled mode type "+Int10_modes.CurMode.type);
            break;
        }
        return (short)color;
    }
}
